package com.dmwork.service.interaction.controller.front.me;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dmwork.common.base.result.R;
import com.dmwork.common.base.util.JwtInfo;
import com.dmwork.common.base.util.JwtUtils;
import com.dmwork.service.interaction.entity.Feed;
import com.dmwork.service.interaction.entity.FeedPictureInfo;
import com.dmwork.service.interaction.entity.vo.FeedInfoVo;
import com.dmwork.service.interaction.entity.vo.FeedPublishVo;
import com.dmwork.service.interaction.feign.CustomerFeignService;
import com.dmwork.service.interaction.feign.MessageFeignService;
import com.dmwork.service.interaction.mq.sender.MessageSender;
import com.dmwork.service.interaction.service.FeedPictureInfoService;
import com.dmwork.service.interaction.service.FeedService;
import com.vdurmont.emoji.EmojiParser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Slf4j
@Api(description = "个人动态功能")
@Transactional
@RestController
@RequestMapping("/front/dm_work/interaction/feed/me")
public class FrontMeFeedController {

    @Autowired
    private FeedService feedService;
    @Autowired
    private FeedPictureInfoService feedPictureInfoService;
    @Autowired
    private MessageSender messageSender;
    @Autowired
    private CustomerFeignService customerFeignService;
    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${custom.feed.picture-count}")
    private Integer feedPictureCount;

    private final String TEMP_STORAGE_FEED_KEY = "temp_storage_feed";


    @ApiOperation("编写动态并发布")
    @PostMapping("publish_feed")
    public R publishFeed(HttpServletRequest request, @RequestBody FeedPublishVo feedPublishVo) {
        JwtInfo jwtInfo = JwtUtils.getCustomerInfoByJwtToken(request);
        Feed feed = new Feed();
        feed.setCustomerId(jwtInfo.getId());
        //对动态内容中的表情包做转换
        if (!StringUtils.isEmpty(feedPublishVo.getComment())) {
            feed.setContent(EmojiParser.parseToAliases(feedPublishVo.getComment()));
        }
        feedService.save(feed);
        if (feedPublishVo.getPictureInfoList() != null && !feedPublishVo.getPictureInfoList().isEmpty()) {
            feed.setPictureCount(feedPublishVo.getPictureInfoList().size());
            feedService.updateById(feed);
            for (FeedPictureInfo feedPictureInfo : feedPublishVo.getPictureInfoList()) {
                feedPictureInfo.setFeedId(feed.getId());
            }
            feedPictureInfoService.saveBatch(feedPublishVo.getPictureInfoList());
        } else {
            feed.setPictureCount(0);
            feedService.updateById(feed);
        }
        // 使用MQ向所有关注的用户投递新动态消息
        messageSender.sendFeedMessage(jwtInfo.getId(), feed.getId(), new HashMap<>());

        //删除redis中的动态草稿数据
        redisTemplate.opsForHash().delete(TEMP_STORAGE_FEED_KEY, jwtInfo.getId());

        return R.ok().message("发布成功");
    }

    @ApiOperation("编写动态并暂存为草稿")
    @PostMapping("temp_storage_feed")
    public R tempStorageFeed(HttpServletRequest request, @RequestBody FeedPublishVo feedPublishVo) {
        JwtInfo jwtInfo = JwtUtils.getCustomerInfoByJwtToken(request);
        redisTemplate.opsForHash().put(TEMP_STORAGE_FEED_KEY, jwtInfo.getId(), feedPublishVo);
        return R.ok().message("暂存成功");
    }

    @ApiOperation("获取上一次未发布的动态草稿")
    @GetMapping("get_temp_storage_feed")
    public R getTempStorageFeed(HttpServletRequest request) {
        JwtInfo jwtInfo = JwtUtils.getCustomerInfoByJwtToken(request);
        if (!redisTemplate.opsForHash().hasKey(TEMP_STORAGE_FEED_KEY, jwtInfo.getId())) {
            return R.ok().message("无草稿");
        } else {
            FeedPublishVo feedPublishVo = (FeedPublishVo) redisTemplate.opsForHash().get(TEMP_STORAGE_FEED_KEY, jwtInfo.getId());
            return R.ok().data("item", feedPublishVo);
        }
    }

    @ApiOperation("删除当前的动态草稿")
    @DeleteMapping("remove_temp_storage_feed")
    public R removeTempStorageFeed(HttpServletRequest request) {
        JwtInfo jwtInfo = JwtUtils.getCustomerInfoByJwtToken(request);
        redisTemplate.opsForHash().delete(TEMP_STORAGE_FEED_KEY, jwtInfo.getId());
        return R.ok().message("删除成功");
    }

    @ApiOperation("删除用户动态")
    @DeleteMapping("remove_feed/{feedId}")
    public R removeFeed(@PathVariable String feedId) {
        feedService.removeById(feedId);
        //获取该动态的所有配图信息，删除
        List<FeedPictureInfo> feedPictureInfoList = feedPictureInfoService.list(new QueryWrapper<FeedPictureInfo>().eq("feed_id", feedId));
        if (feedPictureInfoList.size() > 0) {
            List<String> urlList = new ArrayList<>();
            for (FeedPictureInfo feedPictureInfo : feedPictureInfoList) {
                urlList.add(feedPictureInfo.getPictureUrl());
            }
            //向MQ投递消息，让oss模块去删除图片
            messageSender.sendBatchFileRemoveMessage(urlList, new HashMap<>());
            //删除数据库的配图信息记录
            feedPictureInfoService.remove(new QueryWrapper<FeedPictureInfo>().eq("feed_id", feedId));
        }
        return R.ok().message("删除成功");
    }

    @ApiOperation("获取个人所发布的动态列表")
    @GetMapping("get_own_feed_list/{page}/{limit}")
    public R getOwnFeedList(HttpServletRequest request, @PathVariable Integer page, @PathVariable Integer limit) {
        JwtInfo jwtInfo = JwtUtils.getCustomerInfoByJwtToken(request);
        //获取个人动态基本信息
        Page<Feed> feedPage = feedService.getOwnFeedByCustomerIdPage(jwtInfo.getId(), page, limit);
        if (feedPage.getTotal() == 0) {
            return R.ok().message("暂无数据").data("total", 0);
        }
        List<String> feedIdList = new ArrayList<>();
        for (Feed feed : feedPage.getRecords()) {
            feedIdList.add(feed.getId());
        }
        //获取当前分页的动态用的所有动态图片
        List<FeedPictureInfo> feedPictureInfoList = feedPictureInfoService.list(new QueryWrapper<FeedPictureInfo>().in("feed_id", feedIdList));
        //返回数据的列表
        List<FeedInfoVo> feedInfoVoList = new ArrayList<>();
        //数据组装
        for (Feed feed : feedPage.getRecords()) {
            FeedInfoVo feedInfoVo = new FeedInfoVo();
            //转换Emoji
            if (!StringUtils.isEmpty(feed.getContent())) {
                feed.setContent(EmojiParser.parseToUnicode(feed.getContent()));
            }
            BeanUtils.copyProperties(feed, feedInfoVo);
            feedInfoVo.setCustomerName(jwtInfo.getName());
            feedInfoVo.setAvatar(jwtInfo.getAvatar());
            if (feed.getPictureCount() > 0) {
                List<String> pictureUrlList = new ArrayList<>();
                int count = 0;
                for (FeedPictureInfo feedPictureInfo : feedPictureInfoList) {
                    if (count < feedPictureCount && feedPictureInfo.getFeedId().equals(feed.getId())) {
                        pictureUrlList.add(feedPictureInfo.getPictureUrl());
                        count++;
                    } else if (count >= feedPictureCount) {
                        break;
                    }
                }
                feedInfoVo.setPictureUrlList(pictureUrlList);
            }
            feedInfoVoList.add(feedInfoVo);
        }
        return R.ok().data("total", feedPage.getTotal()).data("rows", feedInfoVoList);
    }

    @ApiOperation("获取所有关注用户以及自己的动态列表")
    @GetMapping("get_feed_list/{page}/{limit}")
    public R getFeedList(HttpServletRequest request, @PathVariable Integer page, @PathVariable Integer limit) {
        JwtInfo jwtInfo = JwtUtils.getCustomerInfoByJwtToken(request);
        //获取当前用户所关注的所有用户的基本信息
        R followedCustomerBaseInfoListResult = customerFeignService.getFollowedCustomerBaseInfoList(jwtInfo.getId());
        if (!followedCustomerBaseInfoListResult.getSuccess()) {
            return R.error().message("获取失败");
        }
        HashMap<String, List<String>> followedCustomerBaseInfoMap = (HashMap<String, List<String>>) followedCustomerBaseInfoListResult.getData().get("result");

        if (followedCustomerBaseInfoMap.size() == 0) {
            return R.ok().message("暂无数据").data("total", 0);
        }

        //按照最新时间分页查询包含这些用户id的动态
        List<String> followedCustomerIdList = new LinkedList<>();
        for (Map.Entry<String, List<String>> entry : followedCustomerBaseInfoMap.entrySet()) {
            followedCustomerIdList.add(entry.getKey());
        }
        //因为也要获取自己的动态，所以用户id要加上自己的
        followedCustomerIdList.add(jwtInfo.getId());

        Page<Feed> feedPage = feedService.getFeedByCustomerIdListPage(followedCustomerIdList, page, limit);
        if (feedPage.getTotal() == 0) {
            return R.ok().message("暂无数据").data("total", 0);
        }
        List<Feed> feedList = feedPage.getRecords();
        List<String> feedIdList = new ArrayList<>();
        for (Feed feed : feedList) {
            feedIdList.add(feed.getId());
        }

        //查询这些动态所用的图片，并分别组装到每一个动态中
        List<FeedPictureInfo> feedPictureInfoList = null;
        if (!feedIdList.isEmpty()) {
            feedPictureInfoList = feedPictureInfoService.list(new QueryWrapper<FeedPictureInfo>().in("feed_id", feedIdList));
        }
        //数据组装
        List<FeedInfoVo> feedInfoVoList = new ArrayList<>();
        for (Feed feed : feedList) {
            FeedInfoVo feedInfoVo = new FeedInfoVo();
            //转换Emoji
            if (!StringUtils.isEmpty(feed.getContent())) {
                feed.setContent(EmojiParser.parseToUnicode(feed.getContent()));
            }
            BeanUtils.copyProperties(feed, feedInfoVo);
            //设置该动态所属用户的用户名和头像
            if (feed.getCustomerId().equals(jwtInfo.getId())) {
                feedInfoVo.setCustomerName(jwtInfo.getName());
                feedInfoVo.setAvatar(jwtInfo.getAvatar());
            } else {
                feedInfoVo.setCustomerName(followedCustomerBaseInfoMap.get(feed.getCustomerId()).get(0));
                feedInfoVo.setAvatar(followedCustomerBaseInfoMap.get(feed.getCustomerId()).get(1));
            }
            if (feed.getPictureCount() > 0 && feedPictureInfoList != null) {
                List<String> pictureUrlList = new ArrayList<>();
                int count = 0; //对图片url计数。业务要求，每个动态的图片数不能超过指定值，所以每找到一张图片的url，就count+1，当count>指定值时，就停止遍历
                for (FeedPictureInfo feedPictureInfo : feedPictureInfoList) {
                    if (count < feedPictureCount && feedPictureInfo.getFeedId().equals(feed.getId())) {
                        pictureUrlList.add(feedPictureInfo.getPictureUrl());
                        count++;
                    } else if (count >= feedPictureCount) {
                        break;
                    }
                }
                feedInfoVo.setPictureUrlList(pictureUrlList);
            }
            //添加已组装好数据的动态
            feedInfoVoList.add(feedInfoVo);
        }

        //将用户id发送到MQ，让消息系统将该用户所有未读动态的消息设置为已读
        messageSender.sendFeedReadMessage(jwtInfo.getId(), new HashMap<>());
        return R.ok().data("total", feedPage.getTotal()).data("rows", feedInfoVoList);
    }

}